ASP.NET Core Web API 入門心得 - 淺談 non-RESTful 的 Route 覆寫
TLDR
- 透過繼承
BasicController並設定[Route("[controller]/[action]")],可統一管理 non-RESTful 架構下的 API 路由。 - 若需覆寫 Controller 層級的路由,直接在 Controller 上使用
[Route]屬性即可。 - 若 Action 需要完全忽略 Controller 層級的路由設定,需在 Action 的
[Route]前綴加上/或~符號。 - 避免在 Controller 與 Action 同時使用
[Route],否則會導致路由路徑串接(Concatenation),產生非預期的 URL。 - 若僅需修改 Action 的 URL 名稱,建議使用
[ActionName]屬性而非[Route]。
統一路由管理與基礎設定
在 non-RESTful 風格的 Web API 中,為了避免重複定義路由,可以建立一個抽象的 BasicController 來統一設定路由規則。
什麼情況下會遇到這個問題: 當專案採用 Controller/Action 格式,且希望減少每個 Controller 重複撰寫路由屬性的維護成本時。
csharp
[ApiController]
[Route("[controller]/[action]")]
public abstract class BasicController : ControllerBase {
}
public class TestRouteController : BasicController {
// URL: /TestRoute/TestAction
[HttpPost]
public void TestAction() {
}
}路由覆寫與路徑串接問題
當現有 API 架構需要調整,或個別 Action 需要特殊路徑時,必須理解 [Route] 屬性在不同層級的行為差異。
什麼情況下會遇到這個問題: 當需要針對特定 Controller 或 Action 進行路徑客製化,卻不希望影響全域設定,或是不小心觸發了預設的路由串接行為時。
路由行為分析
- Controller 層級覆寫:在 Controller 上使用
[Route]會直接取代BasicController的設定。 - Action 層級串接:若 Controller 與 Action 同時定義
[Route],ASP.NET Core 會將兩者路徑進行串接。 - 強制覆寫(忽略前綴):在 Action 的
[Route]前綴加上/或~,可強制忽略 Controller 層級的路由設定。
csharp
[Route("Override/[action]")]
public class TestRouteController : BasicController {
// 情境:Controller 覆寫 Route,Action 不處理
// URL:/Override/OverrideController
[HttpPost]
public void OverrideController() {
}
// 常見誤用:Controller 和 Action 都覆寫,導致路徑串接
// URL:/Override/OverrideAction/Action/OverrideAction
[HttpPost]
[Route("Action/[action]")]
public void OverrideAction() {
}
// 情境:Action 強制忽略 Controller 設定,使用 "/"
// URL:/Action/OnlyAction
[HttpPost]
[Route("/Action/[action]")]
public void OnlyAction() {
}
// 情境:Action 強制忽略 Controller 設定,使用 "~"
// URL:/Action/OnlyAction2
[HttpPost]
[Route("~/Action/[action]")]
public void OnlyAction2() {
}
// 情境:單純修改 Action 名稱,不影響路由結構
// URL:/Override/Rename
[HttpPost]
[ActionName("Rename")]
public void RenameAction() {
}
}結論與建議
- 若要統一 API 命名風格,請優先使用
BasicController進行全域路由定義。 - 若需針對特定 Action 調整路徑,優先考慮使用
[ActionName]屬性,這能避免路由串接帶來的複雜度。 - 若必須使用
[Route]覆寫 Action 路徑,務必加上/或~前綴,以確保路徑符合預期,避免產生冗長的巢狀 URL。
異動歷程
- 2024-04-16 初版文件建立。
